# -*- coding:utf-8 -*-
import configparser
import ctypes
import json
import math
import os
import random
import re
import subprocess
from time import sleep

import chardet
import win32gui
from airtest.core.api import connect_device, wait, snapshot, touch
from airtest.core.cv import Template
from airtest.core.helper import G
import logging


# 读取配置文件
with open('./config/game_config.json', 'r', encoding='utf-8') as f:
    config = json.load(f)
# 设置变量接受参数
game_info = config.get('game', {})
keyword_game = game_info.get('keyword_game')
python64 = game_info.get('python64')
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 配置日志
def logging_config():
    log_dir = 'out/log'
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    log_file = os.path.join(log_dir, 'run.log')

    # 创建一个日志器
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    # 创建一个文件处理器，用于将日志写入文件
    file_handler = logging.FileHandler(log_file, mode='w', encoding='utf-8')
    file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(file_formatter)
    logger.addHandler(file_handler)

    # 创建一个流处理器，用于将日志输出到控制台
    stream_handler = logging.StreamHandler()
    stream_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    stream_handler.setFormatter(stream_formatter)
    logger.addHandler(stream_handler)

    return logger

log = logging_config()
def start_app(start_config):
    # 启动程序，通过配置文件
    with open(start_config,"r",encoding="utf-8") as f:
        data = f.readlines()
    for i in range(len(data)):
        os.startfile(data[i].replace('\n', ''))
        sleep(10)
    return len(data)

def get_hwnds_from_start(counter):
    '''
    开始启动获取窗口个数
    :param counter: 启动程序的个数
    :return:句柄列表
    '''
    all_hwnd_list = []
    dev_hwnds = []

    # 获取所有子窗口
    while len(dev_hwnds) < counter :
        try:
            win32gui.EnumWindows(lambda hwnd, param: param.append(hwnd), all_hwnd_list)
            for hwnd in all_hwnd_list:
                title = win32gui.GetWindowText(hwnd)
                if title and title.find(keyword_game) >= 0:
                    dev_hwnds.append(hwnd)
        except Exception as e:
            print(f"获取窗口句柄时出错: {e}")
        sleep(1)
    dev_hwnds = list(set(dev_hwnds))
    hwnds_titles = []
    for i in range(len(dev_hwnds)):
        title = win32gui.GetWindowText(dev_hwnds[i])
        hwnds_titles.append([dev_hwnds[i], title])
    hwnds_titles.sort(key=lambda x: x[1])  # 按照title排序
    dev_hwnds = [hwnds_titles[i][0] for i in range(len(hwnds_titles))]
    return dev_hwnds

def login_app(hwnd):
    '''
    登录 进入游戏
    :param hwnd: 句柄
    :return:
    '''
    connect_device(f"Windows:///{hwnd}")
    try:
        # 点击进入游戏
        pos = wait(Template(r"./common/picture/tpl_start_game.png", record_pos=(0.039, 0.071), resolution=(969, 807)), 30)
        sleep(2)
        app_touch(pos, [-5, 5], [-1, 1], times=1)
    except:
        print("进入游戏失败")
    sleep(5)
    try:
        # 点击登录游戏
        pos = wait(Template(r"./common/picture/tpl_login_game.png", record_pos=(0.038, 0.153), resolution=(969, 807)), 10)
        sleep(2)
        app_touch(pos, [-5, 5], [-1, 1], times=1)
    except Exception as e:
        title = win32gui.GetWindowText(hwnd)
        print(title+"  登录失败")
        snapshot(f"./out/err/登录失败+{hwnd}.png")

def app_touch(pcos,x_ofset=[0,0],y_ofset=[0,0],times=1):
    '''
    重构点击命令，增加偏移
    :param pcos: 点击控件中心坐标，如（10，20）
    :param x_ofset: x方向偏移区间，[min.max]，默认偏移为0
    :param y_ofset: y方向偏移区间，[min.max]，默认偏移为0
    :param times: 点击次数，默认点击1次
    :return:
    '''
    try:
        x_ofset = random.randint(x_ofset[0], x_ofset[1])
        y_ofset = random.randint(y_ofset[0], y_ofset[1])
        G.LOGGING.info(f"点击坐标为（{(pcos[0] + x_ofset, pcos[1] + y_ofset)}）")
        touch((pcos[0] + x_ofset, pcos[1] + y_ofset),times=times)
    except:
        print("点击失败")

def get_all_devs():
    '''
    获取所有窗口句柄
    :return:
    '''
    # 刷新 -- 获取窗口信息
    # 获取窗口的信息，含设备标题，句柄，角色
    devinfo = []
    hwnds = get_hwnds_from_start(counter=1)
    log.info(f"获取到的窗口句柄为：{hwnds}")
    for i in range(len(hwnds)):
        rect = win32gui.GetWindowRect(hwnds[i])
        # 计算窗口的宽度和高度
        width = rect[2] - rect[0] -16
        height = rect[3] - rect[1] -39
        devinfo.append([i,win32gui.GetWindowText(hwnds[i]),hwnds[i],"","","",f"{width}x{height}"])
        # 对加载出来的设备进行初始化
        sleep(0.1)
    return devinfo

def move_app(hwnds):

    '''
    不缩放 移动到指定的位置
    :param hwnds: 设备句柄列表
    :return:
    '''
    # 1.计算有多少行
    locs = 5  # 有5列窗口程序
    rows = math.ceil(len(hwnds) / locs)
    print(f"一共{rows}行")
    # 2.计算比例
    app_rat = 1 / (locs-1) # 横向覆盖
    try:
        cover_rat = 1 / (rows - 1)  # 覆盖比例
    except:
        cover_rat = 1
    user32 = ctypes.windll.user32
    screen_width = user32.GetSystemMetrics(0)
    screen_height = user32.GetSystemMetrics(1)

    # 5.移动程序窗口
    for i, hwnd in enumerate(hwnds):
        try:
            rect = win32gui.GetWindowRect(hwnd)
            width = rect[2] - rect[0]
            height = rect[3] - rect[1]
            w_jianju = (screen_width - width)
            h_jianju = screen_height - 40 - height
            x = int((i % locs) * w_jianju * app_rat)
            y = int(int(i/locs) * h_jianju * cover_rat)
            win32gui.MoveWindow(hwnd, x, y, width, height, True)
            sleep(2)
        except Exception as e:
            print(f"移动窗口{hwnd}时出错: {e}")

def get_number_from_title(hwnd):
    title = win32gui.GetWindowText(hwnd)
    match = re.search(r'\d+', title)
    number = None
    if match:
        number = match.group()
        log.info(f"提取的数字是: {number}")
    else:
        log.info("未找到数字")
    return number

def OCR_get_text(pic_path, match_str):
    '''
    :param hwnd:
    :param pic_path: 图片默认，放在data/tmp/目录下
    :return:
    '''

    get_value_py = os.path.join(base_dir, "config","get_value_by_ocr.py")

    cmd = [python64, get_value_py, pic_path, f'{match_str}']
    log.info(" ".join(cmd))
    x = -1
    y = -1
    try:
        # 使用 subprocess 模块执行命令并获取返回值
        result = subprocess.run(cmd, capture_output=True, text=True, encoding='UTF-8')

        # 按行分割返回值
        lines = result.stdout.splitlines()
        log.info(lines)
        # 筛选包含“坐标”的行
        for line in lines:
            if "坐标" in line:
                xy = line.split("|")
                x = int(float(xy[1]))
                y = int(float(xy[2]))
                return x,y
        return x,y
    except Exception as e:
        log.info(f"执行命令时出错: {e}")
        return x,y


if __name__ == '__main__':
    print(get_hwnds_from_start(2))
